/*******************************************************************************
 * Copyright (c) 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.core.internal.events;

import java.util.HashSet;
import java.util.Set;

import net.sourceforge.perforce.core.PerforceCorePlugin;
import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.PerforceSynchronizer;
import net.sourceforge.perforce.core.internal.utils.MetaFileWriter;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;

/**
  * @version $Revision: 225 $
  * @author  <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class MetaFileChangeListener implements IResourceChangeListener 
{
	// ------------------------------------------------------------------------------ Public Methods
	
	/** @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) */
	public void resourceChanged(IResourceChangeEvent event) 
	{
		try 
		{
			final Set changedContainers = new HashSet();
			event.getDelta().accept(new IResourceDeltaVisitor() 
			{
				public boolean visit(IResourceDelta delta) throws CoreException 
				{
					IResource resource = delta.getResource();
					
					if (resource.getType() == IResource.ROOT) 
					{
						// continue with the delta
						return true;
					}
					
					if (resource.getType() == IResource.PROJECT)
					{
						// If the project is not accessible, don't process it
						if (!resource.isAccessible()) 
						{
							return false;
						}
					}
					
					String name = resource.getName();
					int kind = delta.getKind();
					
					IResource[] toBeNotified = new IResource[0];
					if (name.equals(MetaFileWriter.IGNORE_FILE)) 
					{
						toBeNotified = handleChangedIgnoreFile(resource, kind);
					}
					
					if (toBeNotified.length > 0)
					{
						for (int i = 0; i < toBeNotified.length; i++) 
						{
							changedContainers.add(toBeNotified[i]);							
						}
					}
					
					return true;
				}
			}, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS);
			
			if (!changedContainers.isEmpty()) 
			{
				PerforceSynchronizer.getInstance().metaFilesChanged((IContainer[]) changedContainers.toArray(new IContainer[changedContainers.size()]));
			}
		} 
		catch (CoreException e) 
		{
			PerforceCorePlugin.log(e.getStatus());
		}
		catch (PerforceException e)
		{
			PerforceCorePlugin.log(e.getStatus());
		}
	}
	
	// ----------------------------------------------------------------------------- Private Methods
	
	protected IContainer[] handleChangedIgnoreFile(IResource resource, int kind) 
	{
		IContainer changedContainer = resource.getParent();
		if (changedContainer.exists()) 
		{
			return new IContainer[] {changedContainer};
		} 
		else 
		{
			return new IContainer[0];
		}
	}
}
